Ccay.UI.Pager = {};
(function(Pager){

	// set defalut config
	var config = {
		pageInf:{
			pageSize:Ccay.UI.Config.pager.defaultSize,
			curPage: 1,
			totalRows: 0,
			totalPages: null
		},
		//是否不显示总记录数
        noTotalRows : false,
        //异步分页，通过url取数，searchCache表示是否缓存搜索条件。
		asynTotalRows : {
			URL: null,
			searchCache : false
		},
		//可选择设定的每页结果数
		pageSizes: Ccay.UI.Config.pager.pageSizes,
		//默认模式，number模式，simple模式
		mode: Ccay.UI.Config.pager.mode, 
		text: {
			pageSizes: $i18n("ccay.common.pager.pageSizes")
	        , curPage: $i18n("ccay.common.pager.curPage")
	        , first: $i18n("ccay.common.pager.first")
	        , prev: $i18n("ccay.common.pager.prev")
	        , next: $i18n("ccay.common.pager.next")
	        , last: $i18n("ccay.common.pager.last")
	        , goTo: $i18n("ccay.common.pager.goTo")
	        , message: $i18n("ccay.common.pager.message")
	        , total: $i18n("ccay.common.pager.total")
    	}, 
		isInitChange: false, 
		fnBeforeChanged: null, 
		fnPageChanged: null,
		modeOp: {btnNum: 6}, 
		showLast: true, 
		showMessage: Ccay.UI.Config.pager.showMessage
	};
	
	var factory = Pager.Factory = {
		 createBtn:function(type, op){
			return "<a class='ccay-pager-btn ccay-pager-{0}' title='{1}'><b type='{0}'></b></a>".formatText(type, op.text[type]);
		},
		createNumBtn: function (html, type, text, css) {
			html.push("<a class='ccay-pager-numbtn {2}'><span type='{0}'>{1}</span></a>".formatText(type, text, css || ""));
		},
		buildNumBtns: function(pagerOp, pageInf, text, modeOp) {
			if(pageInf.totalPages > 1)
			{
				var html = [];
				if(!modeOp)
					modeOp = pagerOp.modeOp;
				if(!text)
					text = pagerOp.text;
				var btnNum,
					splitNum,
					startPage;
				if(modeOp.btnNum > pageInf.totalPages)
				{
					btnNum = pageInf.totalPages - 2;
					splitNum = 0;
					startPage = 2;
				}
				else
				{
					btnNum = pageInf.curPage > 99999 ? 4 : modeOp.btnNum;
					splitNum = parseInt(btnNum/2);
					startPage =pageInf.curPage - splitNum + 1;
					if(startPage < 2)
						startPage = 2;
					else if (pageInf.totalPages - splitNum < pageInf.curPage)
						startPage -= pageInf.curPage - pageInf.totalPages + splitNum;
					if(startPage == 1)
						startPage = 2;
				}
				if(pageInf.curPage > 1)
					this.createNumBtn(html, 'prev', text.prev);
				this.createNumBtn(html, 'num', 1, pageInf.curPage == 1 ? 'cur' :'');
				if(splitNum > 0 && startPage > 2)
					this.createNumBtn(html, '', '…', 'dot');
				for(var i=0; i<btnNum; i++, startPage++)
				{
					if(startPage < pageInf.totalPages)
						this.createNumBtn(html, 'num', startPage, startPage == pageInf.curPage ? 'cur' :'');
				}
				if(modeOp.showLast)
				{
					if(splitNum > 0 && startPage < pageInf.totalPages)
						this.createNumBtn(html, '', '…', 'dot');
					this.createNumBtn(html, 'num', pageInf.totalPages, pageInf.curPage == pageInf.totalPages ? 'cur' :'');
				}
				if(pageInf.curPage != pageInf.totalPages)
					this.createNumBtn(html, 'next', text.next);
				return html.join('');
			}
			return '';
		},
		getTotalPage: function (pageInf) {
			return pageInf.totalRows > 0 ? (parseInt(pageInf.totalRows/pageInf.pageSize) + (pageInf.totalRows % pageInf.pageSize > 0 ? 1 : 0)) : 1;
		},
		setDisabled:function(btn, disabled){
			btn.toggleClass('disabled', disabled);
			return this;
		},
		setBtnState: function (pager, pageInf){
			var isFirst = pageInf.curPage == 1,
				isLast = pageInf.curPage == pageInf.totalPages;
			this.setDisabled(pager.getFirstBtn(), isFirst).setDisabled(pager.getPrevBtn(), isFirst);
			this.setDisabled(pager.getNextBtn(), isLast).setDisabled(pager.getLastBtn(), isLast);
			this.setDisabled(pager.getGroupGoto(), isFirst && isLast);
		},
		updateStatus: function (pager, panel, pageInf) {
			var txtPage = pager.getGotoInput();
			pager.getRecordsTotal().text(pageInf.totalRows);
			pager.getPagesizesSelect().val(pageInf.pageSize);
			if(pager.dom.hasClass('ccay-pager-number'))
			{
				// 易用性，默认显示为1，随页面跳转联动显示
				//if(txtPage.val())
					txtPage.val(pageInf.curPage);
				pager.getGroupNumBtns().html(factory.buildNumBtns(pager.op, pageInf));
				pager.getGroupGoto().toggleClass('hide', pageInf.totalPages == 1);
			}
			else
			{
				txtPage.val(pageInf.curPage);
				pager.getCurrentPage().text(pageInf.curPage);
				pager.getTotalPages().text(pageInf.totalPages);
				factory.setBtnState(pager, pageInf);
			}
		},
		checkPage: function (op) {
			if (isNaN(op.pageInf.curPage))
				return false;
			else if((op.pageInf.curPage > op.pageInf.totalPages)&&(!op.noTotalRows))
				op.pageInf.curPage = op.pageInf.totalPages;
			else if(op.pageInf.curPage > Ccay.UI.Config.pager.maxPages){
			    op.pageInf.curPage = Ccay.UI.Config.pager.maxPages;
			}
			return true;
		},
		setPager: function(pager, pageInf) {
			var panel = pager.getPagerPanel().toggleClass("hide", !pageInf.totalRows),
				textPanel =  pager.getPagerText();
			textPanel.length && textPanel.toggleClass("hide", pageInf.totalRows > 0);
			pager.dom.toggleClass("hide", !pageInf.totalRows);
			
			// 无数据时 提示提到 中间
			if(pageInf.totalRows == 0){
				var pageParent = $("#"+pager.id).parent(); 
				if( pageParent.attr("gtgrid_init") ){//gt_grid
					var curDiv = $( pageParent.getCcayGridManager().viewport);
					!curDiv.find(".grid-no-result").length && curDiv.append('<div class="grid-no-result" style="position: absolute;">'+$i18n("ccay.common.label.noresult")+'</div>');
					var no_result = curDiv.find(".grid-no-result"),
						width = ( curDiv.width() - no_result.width() )/2;
					no_result.css({left:width,top:22});
				}else{//igrid
					var currBody = textPanel.parents(".ccay-igrid").find(".ccay-igrid-body");
					var igridOp = textPanel.parents(".ccay-igrid").manager().op;
					var noResultI18n = "ccay.common.label.noresult";
					//如用户设置自定义提示，则显示自定义提示
					if(igridOp && null != igridOp.noResultI18n){
						noResultI18n = igridOp.noResultI18n;
					}
					!currBody.find(".grid-no-result").length && currBody.append('<div class="grid-no-result">'+$i18n(noResultI18n)+'</div>');
				}
			}else {
				var pageParent = $("#"+pager.id).parent();
				if(pageParent.attr("gtgrid_init")){//gt_grid
					pageParent.find(".grid-no-result,.grid-no-result").remove();
				}else{//igrid
					pageParent.parent().find(".igrid-no-result,.grid-no-result").remove();
				}
			}
			
			pageInf.totalRows && factory.updateStatus(pager, panel, pageInf);
		},
		triggerChanged: function(pager, pageInf, fnChanged) {
			var op = pager.op;
			if(factory.checkPage(op))
			{
				factory.setPager(pager, pageInf);
				var fnChanged = op.fnPageChanged;
				fnChanged && fnChanged(pageInf, pager);
			}
			// 分页后滚动到锚定区
			if (op.scrollContainer || op.anchorPanel) {
				factory.scrollToAnchor(pager, op);
			}
		},
		scrollToAnchor: function (pager, op) {
			var scrollContainer = op.scrollContainer ? $(op.scrollContainer) : $(window),
				anchorPanelOffset = op.anchorPanel && $(op.anchorPanel).offset(),
				anchorPanelTop = anchorPanelOffset ? anchorPanelOffset.top - 30 : 0;
			scrollContainer.scrollTop(anchorPanelTop);
		}
	};
	
	//结构构造器
    factory.Builder = {
        init: function (pager, op) {
            var html = [];
            html.push('<div class="ccay-pager-panel">');
            this.renderMessage(html, op);
            this.renderPageSizes(html, op);
            this.renderBtn(html, op);
            this.renderGoTo(html, op);
            op.showMessage && html.push('</div><div class="ccay-pager-text hide">', $i18n(''), '</div>');
            pager.dom.addClass('ccay-pager').html(html.join(''));
            this.end(pager, op);
        },
        renderMessage: function (html, op) {
			
		},
        renderPageSizes: function (html, op) {
			var ddl = [];
			//如果用户手工设置了分页显示条数，并且只有一个，就无需显示下拉框
			var pageSizesClass = "ccay-pager-group pagesizes";
			if(op.pageSizes.length == 1){
				pageSizesClass = "ccay-pager-group msg";
				ddl.push(op.pageSizes[0]);
			}else{
				ddl.push("<select class='ccay-pager-pagesize'>");
				for(var i=0, size = op.pageSizes[0]; size; i++, size = op.pageSizes[i])
				{
					ddl.push("<option type='psize' ", op.pageInf.pageSize == size ? "selected " : "", "value='", size, "'>", size, "</option>");
				}
				ddl.push('</select>');
			}
			html.push('<div class="',pageSizesClass,'">', op.text.pageSizes.formatText(ddl.join('')), '</div>');
		},
        renderBtn: function (html, op) {
			
		},
		renderGoTo: function (html, op) {
			html.push('<div class="ccay-pager-group goto hide">',
						'<input class="ccay-pager-page" type="text" value="">',
						'<a class="ccay-pager-numbtn"><span type="goto">{0}</span></a>'.formatText(op.text.goTo),
						'</div>');
		},
		end: function(pager, op){
			
		}
	};
	
	var pagerExt = {
		renderMessage: function (html, op) {
			if(op.showLast)
			{
				if (op.noTotalRows)
					html.push('<div class="ccay-pager-group msg">',
						op.text.curPage.formatText(
							"<font class='curPage'>" + op.pageInf.curPage + "</font>"
						), '</div>');
			    else
					html.push('<div class="ccay-pager-group msg">',
						op.text.message.formatText(
							"<font class='curPage'>" + op.pageInf.curPage + "</font>",
							"<font class='totalPage'>" + op.pageInf.totalPages + "</font>",
							"<font class='total'>" + op.pageInf.totalRows + "</font>"
						), '</div>');
			}
		},
		renderBtn: function (html, op) {
			html.push('<div class="ccay-pager-group btns">',
						factory.createBtn('first', op),
						factory.createBtn('prev', op),
						factory.createBtn('next', op));
			if ((op.showLast)&&(!op.noTotalRows))
				html.push(factory.createBtn('last', op));
			html.push('</div>');
		},
		end: function(pager, op){
			factory.setBtnState(pager, op.pageInf);
		}
	};
	
	var pagerNumberExt = {
		renderMessage:function (html, op){
			if((op.showLast)&&(!op.noTotalRows))
				html.push('<div class="ccay-pager-group msg">',
					op.text.total.formatText("<font class='total'>" + op.pageInf.totalRows + "</font>"),
					'</div>');
		},
		renderBtn: function (html, op){
			op.modeOp.showLast = op.showLast;
			html.push('<div class="ccay-pager-group numbtns">',
					factory.buildNumBtns(op, op.pageInf, op.text, op.modeOp),
					'</div>');
		},
		end: function (pager, op) {
			pager.dom.addClass('ccay-pager-number');
		}
	};
	
	//事件绑定
	factory.EventBinder = {
		init: function (pager, op) {
            this.bindGroupBtnsClick(pager, op);
            this.bindPagesizesChange(pager, op);
            this.bindGotoInputKeydown(pager, op);
        },
		bindGroupBtnsClick: function(pager, op) {
			pager.getPagerPanel().delegate('a', "click", function(e){
				var trigger = $(this);
				pager.pageChange(trigger, pager, op);
			});
		},
		bindPagesizesChange: function(pager, op) {
			pager.getPagesizesSelect().change(function(e) {
				pager.pageSizeChange(pager, op);
			});
		},
		bindGotoInputKeydown: function(pager, op) {
			pager.getGotoInput().keydown(function (e) {
				if(e.keyCode == 13)
					pager.getGotoBtn().click();
			});
		}
	};
	
	//define control flow
	var flow = {
		preInit: function (pager, op) {
			op.pageSizes = op.pageSizes || Ccay.UI.Config.pager.pageSizes;
			if(!op.pageInf.totalPages)
				op.pageInf.totalPages = factory.getTotalPage(op.pageInf);
		},
		init: function (pager, op) {
			var width = pager.dom.width(),
				isShort = width == 0 ? 0 : width < 500;
			$.extend(factory.Builder, pagerExt);
			if (!isShort && op.mode == 'number' && op.modeOp) {
				$.extend(factory.Builder, pagerNumberExt);
			}
		},
		build: function (pager, op) {
			factory.Builder.init(pager, op);
		},
		bindEvent: function (pager, op) {
			factory.EventBinder.init(pager, op);
		},
		initComplete: function(pager, op){
			op.isInitChange && factory.triggerChanged(pager, op.pageInf);
		},
		initAjax:function(pager,op,ajax){
		
		},
		preBindData:function(pager,op,data,pageVO){
		
		},
		bindData:function(pager,op,data){
		
		},
		bindDataComplete:function(pager,op){
		
		},
		complete: function (pager, op) {
			pager.dom.data("builded", true);
		}
	};
	//define control manager
	var manager = {
		//overwrite base
		//get dom object
		getPagerPanel: function() {
			return DomClass.getProp(this, this.dom, 'pagerPanel', '.ccay-pager-panel');
		},
		getPagerText: function() {
			return DomClass.getProp(this, this.dom, 'pagerText', '.ccay-pager-text');
		},
		getGroupMsg: function() {
			return DomClass.getProp(this, this.getPagerPanel(), 'groupMsg', '.ccay-pager-group.msg');
		},
		getRecordsTotal: function() {
			return DomClass.getProp(this, this.getGroupMsg(), 'recordsTotal', 'font.total', false);
		},
		getCurrentPage: function() {
			return DomClass.getProp(this, this.getGroupMsg(), 'currentPage', 'font.curPage', false);
		},
		getTotalPages: function() {
			return DomClass.getProp(this, this.getGroupMsg(), 'totalPages', 'font.totalPage', false);
		},
		getGroupPagesizes: function() {
			return DomClass.getProp(this, this.getPagerPanel(), 'groupPagesizes', '.ccay-pager-group.pagesizes');
		},
		getPagesizesSelect: function() {
			return DomClass.getProp(this, this.getGroupPagesizes(), 'pagesizesSelect', '.ccay-pager-pagesize');
		},
		getGroupNumBtns: function() {
			return DomClass.getProp(this, this.getPagerPanel(), 'groupNumBtns', '.ccay-pager-group.numbtns');
		},
		getGroupBtns: function() {
			return DomClass.getProp(this, this.getPagerPanel(), 'groupBtns', '.ccay-pager-group.btns');
		},
		getFirstBtn: function() {
			return DomClass.getProp(this, this.getGroupBtns(), 'firstBtn', '.ccay-pager-first', false);
		},
		getPrevBtn: function() {
			return this.getFirstBtn().next();
		},
		getNextBtn: function() {
			return this.getPrevBtn().next();
		},
		getLastBtn: function() {
			return this.getNextBtn().next();
		},
		getGroupGoto: function() {
			return DomClass.getProp(this, this.getPagerPanel(), 'groupGoto', '.ccay-pager-group.goto');
		},
		getGotoInput: function() {
			return DomClass.getProp(this, this.getGroupGoto(), 'gotoInput', 'input.ccay-pager-page', false);
		},
		getGotoBtn: function() {
			return this.getGotoInput().next().children();
		},
		//get object
		getPageInf: function () {
			return this.op.pageInf;
		},
		//operate funciton
		changePage: function (pageInf) {
			var oldPageInf = this.op.pageInf;
			$.extend(oldPageInf, pageInf);
			factory.triggerChanged(this, oldPageInf);
		},
		pageChange: function (trigger, pager, pagerOp) {
			var btnType = trigger.children("[type]").attr('type');
			if(btnType && !trigger.hasClass('disabled'))
			{
				var pageInf = pagerOp.pageInf,
					oldTotalPages = pageInf.totalPages,
					oldPage = pageInf.curPage,
					fnBeforeChanged = pagerOp.fnBeforeChanged;
				switch(btnType)
				{
					case "first":
						pageInf.curPage = 1;
						break;
					case "prev":
						pageInf.curPage -= 1;
						break;
					case "next":
						pageInf.curPage += 1;
						break;
					case "last":
						pageInf.curPage = pageInf.totalPages;
						break;
					case "goto":
						var txt = pager.getGotoInput(),
							page = txt.val() * 1;
						// 跳转为当前页，则不做处理
						if(oldPage == page || isNaN(page) || page < 1 || ! /^[0-9\ ]+$/.test(page))
						{
							txt.val(oldPage);
							return;
						}
						pageInf.curPage = page;
						break;
					case "num":
						var btn = trigger.parent();
						btn.siblings('.cur').removeClass('cur');
						btn.addClass('cur');
					pageInf.curPage = trigger.text() * 1;
						break;
					default:
						return;
				}
				if(!fnBeforeChanged || fnBeforeChanged(pager, pageInf, oldPage, pageInf.pageSize, factory.triggerChanged, oldTotalPages) !== false)
					factory.triggerChanged(pager, pageInf);
			}
		},
		pageSizeChange: function (pager, pagerOp) {
			var pageInf = pagerOp.pageInf;
			if(pageInf)
			{
				var oldTotalPages = pageInf.totalPages,
					oldPage = pageInf.curPage,
					oldPageSize = pageInf.pageSize;
				pageInf.curPage = 1;
				pageInf.pageSize = pager.getPagesizesSelect().val() * 1;
				pageInf.totalPages = factory.getTotalPage(pageInf);
				var fnBeforeChanged = pagerOp.fnBeforeChanged;
				if(!fnBeforeChanged || fnBeforeChanged(pager, pageInf, oldPage, oldPageSize, factory.triggerChanged, oldTotalPages) !== false)
					factory.triggerChanged(pager, pageInf);
			}
		},
		reInit: function (op) {
			op = $.extend(this.op, op);
			op.pageInf.totalPages = factory.getTotalPage(op.pageInf);
			factory.setPager(this, op.pageInf);
		}
	};
	
	//define inner functions
	var helper = {};
	
	//create XControl
	var XPager = Ccay.UI.XControl("XPager", flow, config, manager);
	
	//custom  && handler
	
	// create jquery plugin
    $.fn.pager = function(op, grid) {
		// 原构造过程
		var create = function(obj, opt) {
			if (!obj.data("builded")) {
				new XPager(obj, opt);
			} else {
				obj.manager().reInit(opt);
			}
		}

		// 变量声明
		var url, searchCache, searchVO;
		// 参数初始化
		if ((!grid) || ((grid) && (op.pageInf.hasOwnProperty("resultMode")))) {
			if (!op.noTotalRows) {
				if (op.hasOwnProperty("asynTotalRows")) {
					url = op.asynTotalRows.URL;
					searchCache = op.asynTotalRows.searchCache;
				}
			}
		}
		//alert(url);
		if (url) {
			var params, filter;
			// 搜索条件处理及 url格式化
			if (grid) {
				var loadType = grid.op._loadType;
				// 取缓存
				searchVO = this.data("searchVO");
				if (searchVO == undefined) {
					searchVO = {
						params : "",
						filter : ""
					};
				}
				//取查询参数及过滤条件
				if ((grid.op.operation.search)&&(grid.op.operation.search.panel)) {
					params = $(grid.op.operation.search.panel).jsonData();
				}
				if (grid.op.allowFilter) {
					filter = op.pageInf.filter;
				}
				url = url.formatField(op.pageInf);
			} else {
				url = url.formatText(Ccay.UI.Config.pager.defaultSize, 1, 0);
			}
			if ((!searchCache) || (JSON.stringify(params) != JSON.stringify(searchVO.params)) || (filter != searchVO.filter)) {
				// 异步分页处理，只有刷新及搜索时进行
				if ((loadType == undefined) || (loadType == "search")) {
					// 缓存搜索条件
					searchVO.params = params;
					searchVO.filter = filter;
					this.data("searchVO", searchVO);
					var current = this;
					Ccay.doGet(url, params, function(result) {
								op.pageInf.totalRows = result.pageVO.totalRows;
								current.data("totalRows", op.pageInf.totalRows);
								create(current, op);
							});
				}
			} else {
				if ((op.pageInf.curPage == 1) && (this.manager().op.pageInf.curPage != op.pageInf.curPage)) {
					// 缓存模式下重新搜索后当前页跳至首页
					this.manager().op.pageInf.curPage = op.pageInf.curPage;
				} else {
					// 刷新并重新搜索后，缓存模式下的记录总数
					this.manager().op.pageInf.totalRows = this.data("totalRows");
				}
				create(this, this.manager().op);
			}
		} else {
			if (op.noTotalRows) {
				if (grid) {
					if (grid.getAllRecords().length < op.pageInf.pageSize) {
						op.pageInf.totalRows = op.pageInf.curPage * op.pageInf.pageSize;
					} else {
						op.pageInf.totalRows = op.pageInf.endIndex + 1;
					}
				}
			}
			create(this, op);
		}
	}
	
})(Ccay.UI.Pager);